﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Prism.Mvvm;
using Prism.Commands;
using Panuon.UI.Silver;
using Models;
using System.Collections.ObjectModel;
using System.Windows;
using Client.DAL;
using Client.Common;
using Microsoft.Win32;
using NPOI.SS.UserModel;
using System.IO;
using NPOI.XSSF.UserModel;
using NPOI.HSSF.UserModel;
using System.Globalization;
using Prism.Regions;
using System.Windows.Controls;
using Newtonsoft.Json;

namespace Client.ViewModels
{
    public class CodeManageViewModel : BindableBase, IRegionMemberLifetime
    {
        #region 绑定属性

        //列表
        private ObservableCollection<CodeStatusModel> _codeList;

        public ObservableCollection<CodeStatusModel> CodeList
        {
            get { return _codeList; }
            set { SetProperty(ref _codeList, value, "CodeList"); }
        }

        //产品列表
        private ObservableCollection<ProductModel> _proList;

        public ObservableCollection<ProductModel> ProList
        {
            get { return _proList; }
            set { SetProperty(ref _proList, value, "ProList"); }
        }

        //选择的产品
        private object _selectedPro;

        public object SelectedPro
        {
            get { return _selectedPro; }
            set { SetProperty(ref _selectedPro, value, "SelectedPro"); }
        }

        //查询起始时间
        private DateTime _startDate;

        public DateTime StartDate
        {
            get { return _startDate; }
            set { SetProperty(ref _startDate, value, "StartDate"); }
        }

        //查询结束时间
        private DateTime _endDate;

        public DateTime EndDate
        {
            get { return _endDate; }
            set { SetProperty(ref _endDate, value, "EndDate"); }
        }

        //转圈状态
        private Visibility _showRunning;

        public Visibility ShowRunning
        {
            get { return _showRunning; }
            set { SetProperty(ref _showRunning, value, "ShowRunning"); }
        }

        private bool _runCy;

        public bool RunCy
        {
            get { return _runCy; }
            set { SetProperty(ref _runCy, value, "RunCy"); }
        }

        //查询按钮状态
        private bool _btnQueryWorking;

        public bool BtnQueryWorking
        {
            get { return _btnQueryWorking; }
            set { SetProperty(ref _btnQueryWorking, value, "BtnQueryWorking"); }
        }

        //作废按钮状态
        private bool _btnCancelWorking;

        public bool BtnCancelWorking
        {
            get { return _btnCancelWorking; }
            set { SetProperty(ref _btnCancelWorking, value, "BtnCancelWorking"); }
        }

        //导出按钮状态
        private bool _btnExportWorking;

        public bool BtnExportWorking
        {
            get { return _btnExportWorking; }
            set { SetProperty(ref _btnExportWorking, value, "BtnExportWorking"); }
        }

        #endregion 绑定属性

        #region 属性

        #endregion 属性

        #region 命令

        public DelegateCommand QueryCommand { get; private set; }
        public DelegateCommand<DataGrid> CancelCommand { get; private set; }
        public DelegateCommand ExportCommand { get; private set; }
        public DelegateCommand GetProCommand { get; private set; }

        #endregion 命令

        #region 构造函数

        public CodeManageViewModel()
        {
            ShowRunning = Visibility.Visible;
            BtnCancelWorking = false;
            BtnQueryWorking = false;
            BtnExportWorking = false;
            StartDate = DateTime.Now;
            EndDate = DateTime.Now;
            QueryCommand = new DelegateCommand(QueryCodeList);
            CancelCommand = new DelegateCommand<DataGrid>(CancelCode);
            ExportCommand = new DelegateCommand(ExportToXls);
            GetProCommand = new DelegateCommand(GetProList);
            _proList = new ObservableCollection<ProductModel>();
            _codeList = new ObservableCollection<CodeStatusModel>();
            GetProList();
        }

        #endregion 构造函数

        #region 方法

        #region 查询

        private StateModel getListState;

        private async void QueryCodeList()
        {
            if (SelectedPro is null || !(SelectedPro is ProductModel pro))
            {
                Comm.ShowErr("必须选择产品", "编码查询", MessageBoxIcon.Error);
                return;
            }
            void callback(RetModel rm)
            {
                if (getListState.CurStep != Steps.Send)
                    return;
                getListState.RM = rm;
                if (rm.Success)
                    getListState.RM.Data = rm.Data is null ? null : JsonConvert.DeserializeObject<List<CodeStatusModel>>(rm.Data.ToString());
                getListState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            ShowRunning = Visibility.Visible;
            RunCy = true;
            BtnQueryWorking = true;
            CodeList.Clear();
            getListState = new StateModel { CurStep = Steps.Send };
            CodeSrv.GetStatusList(callback, pro.Id, StartDate.ToString("yyyy-MM-dd 00:00:00"), EndDate.ToString("yyyy-MM-dd 23:59:59"), 0);
            await getListState.CheckState(10);

            if (getListState.CurStep != Steps.Succ)
            {
                Comm.ShowErr(getListState.ErrStr, "查询编码", MessageBoxIcon.Error);
            }
            else
            {
                if (getListState.RM.Data is List<CodeStatusModel> l && l?.Count > 0)
                    CodeList.AddRange(l);
            }
            ShowRunning = Visibility.Hidden;
            RunCy = false;
            BtnQueryWorking = false;
        }

        #endregion 查询

        #region 作废

        private StateModel cancelState;

        private async void CancelCode(DataGrid d)
        {
            if (d.SelectedItems is null || d.SelectedItems?.Count < 1)
            {
                Comm.ShowErr("必须选择要作废的编码", "编码作废", MessageBoxIcon.Error);
                return;
            }
            void callback(RetModel rm)
            {
                if (cancelState.CurStep != Steps.Send)
                    return;
                cancelState.RM = rm;
                cancelState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            var SelectedCode = d.SelectedItems;
            BtnQueryWorking = true;
            ShowRunning = Visibility.Visible;
            RunCy = true;
            string err = "";
            for (int i = 0; i < SelectedCode.Count; i++)
            {
                if (!(SelectedCode[i] is CodeStatusModel itm))
                {
                    err = "选择的项目不正确！";
                    return;
                }
                cancelState = new StateModel { CurStep = Steps.Send };
                CodeSrv.CancelCode(callback, itm.CodeId);
                await cancelState.CheckState(10);
                err += cancelState.CurStep != Steps.Succ ? cancelState.ErrStr : "";
            }

            if (string.IsNullOrEmpty(err))
            {
                QueryCodeList();
            }
            else
            {
                Comm.ShowErr(err, "编码作废", MessageBoxIcon.Error);
            }
            BtnQueryWorking = false;
            ShowRunning = Visibility.Hidden;
            RunCy = false;
        }

        #endregion 作废

        #region 导出

        private async void ExportToXls()
        {
            try
            {
                if (CodeList.Count < 1)
                {
                    Comm.ShowErr("没有要导出的数据", "导出编码");
                    return;
                }
                string fileName = "";
                SaveFileDialog f = new SaveFileDialog
                {
                    Filter = "Excel 97-2003|*.xls|Excel 2007|*.xlsx",
                    FileName = null
                };
                f.ShowDialog();
                if (f.FileName.IsNullOrEmpty())
                    return;
                fileName = f.FileName;
                string err = "";
                var x = await Task.Run(() =>
                {
                    try
                    {
                        ShowRunning = Visibility.Visible;
                        RunCy = true;
                        BtnExportWorking = true;
                        IWorkbook workBook = null;
                        FileInfo fi = new FileInfo(fileName);
                        if (fi.Extension.ToLower() == ".xlsx")
                            workBook = new XSSFWorkbook();
                        else if (fi.Extension.ToLower() == ".xls")
                            workBook = new HSSFWorkbook();
                        else
                            throw new Exception("文件后缀不正确！");
                        ISheet sheet = workBook.CreateSheet("编码");

                        #region 表头

                        IRow row = sheet.CreateRow(0);
                        row.CreateCell(0).SetCellValue("长编号");
                        row.CreateCell(1).SetCellValue("产品编号");
                        row.CreateCell(2).SetCellValue("年度");
                        row.CreateCell(3).SetCellValue("随机码");
                        row.CreateCell(4).SetCellValue("后缀");
                        row.CreateCell(5).SetCellValue("生成时间");
                        row.CreateCell(6).SetCellValue("出库状态");
                        row.CreateCell(7).SetCellValue("兑换状态");

                        #endregion 表头

                        Converters.ChargeFlagConverter chgCvt = new Converters.ChargeFlagConverter();
                        Converters.SaleFlagConverter salCvt = new Converters.SaleFlagConverter();
                        for (int i = 0; i < CodeList.Count; i++)
                        {
                            int idx = i + 1;
                            row = sheet.CreateRow(idx);
                            row.CreateCell(0).SetCellValue(CodeList[i].CodeBaseInfo.CodeFull);
                            row.CreateCell(1).SetCellValue(CodeList[i].CodeBaseInfo.CodePro);
                            row.CreateCell(2).SetCellValue(CodeList[i].CodeBaseInfo.CodeYear);
                            row.CreateCell(3).SetCellValue(CodeList[i].CodeBaseInfo.CodeMain);
                            row.CreateCell(4).SetCellValue(CodeList[i].CodeBaseInfo.CodeSuffix);
                            row.CreateCell(5).SetCellValue(CodeList[i].CodeBaseInfo.GenDate);
                            row.CreateCell(6).SetCellValue(salCvt.Convert(CodeList[i].SaleFlag, typeof(string), new object(), CultureInfo.CurrentCulture).ToString());
                            row.CreateCell(7).SetCellValue(chgCvt.Convert(CodeList[i].ChargeFlag, typeof(string), null, CultureInfo.CurrentCulture).ToString());
                        }
                        //保存文件
                        FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                        workBook.Write(fs);
                        fs.Dispose();
                        return true;
                    }
                    catch (Exception ex)
                    {
                        err = ex.Message;
                        return false;
                    }
                });
                if (x)
                {
                    Comm.ShowErr("保存成功", "导出编码", MessageBoxIcon.Success);
                }
                else
                {
                    Comm.ShowErr(err, "导出编码", MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                Comm.ShowErr("导出失败\r\n错误信息:" + ex.Message, "导出编码");
            }
            BtnExportWorking = false;
            ShowRunning = Visibility.Hidden;
            RunCy = false;
        }

        #endregion 导出

        #region 读取产品列表

        private StateModel getProListState;

        private async void GetProList()
        {
            void callback(RetModel rm)
            {
                if (getProListState.CurStep != Steps.Send)
                    return;
                getProListState.RM = rm;
                if (rm.Success)
                    getProListState.RM.Data = rm.Data is null ? null : JsonConvert.DeserializeObject<List<ProductModel>>(rm.Data.ToString());
                getProListState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            ShowRunning = Visibility.Visible;
            RunCy = true;
            ProList.Clear();
            getProListState = new StateModel { CurStep = Steps.Send };
            ProSrv.GetProList(callback, null, null, 0);
            await getProListState.CheckState(10);
            if (getProListState.CurStep != Steps.Succ)
            {
                Comm.ShowErr(getProListState.ErrStr, "读取产品信息", MessageBoxIcon.Error);
            }
            else
            {
                if (getProListState.RM.Data is List<ProductModel> l && l?.Count > 0)
                    ProList.AddRange(l);
                if (ProList.Count > 0)
                    SelectedPro = ProList[0];
            }
            ShowRunning = Visibility.Hidden;
            RunCy = false;
        }

        #endregion 读取产品列表

        public bool KeepAlive => false;

        #endregion 方法
    }
}